#include "stdafx.h"
#include "HttpHeader.h"

using namespace std;

BOOL CHttpRequest::PreProcess(const uchar * payload, UINT32 payloadlen)
{
	string strRequest(reinterpret_cast<const char*>(payload));
	size_t pos = string::npos;
	if ((pos = strRequest.find("\r\n")) == string::npos)
		return false;

	if (mRequestLine.PreProcess(strRequest.substr(0, pos)) == FALSE) {
		return FALSE;
	}

	if (mRequestHeader.PreProcess(strRequest.substr(0, pos)) == FALSE) {
		return FALSE;
	}

	return TRUE;
}

BOOL CHttpResponse::PreProcess(const uchar * payload, UINT32 payloadlen)
{
	mChunked = FALSE;

	string strResponse(reinterpret_cast<const char*>(payload));
	size_t pos = string::npos;
	if ((pos = strResponse.find("\r\n")) == string::npos)
		return FALSE;

	if (mResponseLine.PreProcess(strResponse.substr(0, pos)) == FALSE) {
		return FALSE;
	}

	if (mResponseEntity.PreProcess(strResponse.substr(pos + 2, strResponse.length() - pos - 2)) == FALSE) {
		return FALSE;
	}

	map<string, string>::iterator it = mResponseEntity.mColums.find("Content-Length");
	if (it == mResponseEntity.mColums.end()) {
		DEBUG_PRINT("Error condition: not found Content-Length\n");
		it = mResponseEntity.mColums.find("Transfer-Encoding");
		if (it == mResponseEntity.mColums.end())
			return FALSE;
		else {
			if (it->second != " chunked") {
				return FALSE;
			}
			else {
				mChunked = TRUE;
			}
		}
	}
	else {
		mContentLength = atoi(it->second.c_str());
	}
	return TRUE;
}

BOOL CHttpRequestLine::PreProcess(std::string data)
{
	size_t pos = string::npos;
	if ((pos = data.find(" ")) == string::npos)
		return false;
	strMethod = data.substr(0, pos);
	
	URI = data.substr(pos + 1, data.length() - pos - 1);
	if ((pos = URI.find(" ")) == string::npos)
		return false;
	URI = URI.substr(0, pos);

	if ((pos = data.rfind(" ")) == string::npos)
		return false;
	version = data.substr(pos + 1, data.length() - pos - 1);

	return TRUE;
}

std::string CHttpRequestLine::RequestContent()
{
	string val;
	size_t pos = URI.rfind("/");
	if (pos == string::npos)
		return std::string();

	if (pos == URI.length())
		return std::string();
	val = URI.substr(pos + 1, URI.length() - pos - 1);

	if ((pos = val.find("?")) == string::npos) {
		return val;
	}

	return val.substr(0, pos);
}

std::string CHttpRequestLine::RequestPostfix()
{
	string content = RequestContent();
	size_t pos = content.rfind(".");
	if (pos == string::npos)
		return std::string();

	return content.substr(pos + 1, content.length() - pos - 1);
}

BOOL CHttpRequestHeader::PreProcess(std::string data)
{
	return TRUE;
}

BOOL CHttpEntity::PreProcess(std::string data)
{
	size_t pos = string::npos;
	do {
		pos = data.find("\r\n");
		if (pos == string::npos) {
			break;
		}
		string line = data.substr(0, pos);
		data = data.substr(pos + 2, data.length() - pos - 2);

		size_t pos2 = line.find(":");
		if (pos2 == string::npos)
			continue;
		string key = line.substr(0, pos2);
		string val = line.substr(pos2 + 1, line.length() - pos2 - 1);

		mColums.insert(make_pair(key, val));
	} while (pos != string::npos);

	return TRUE;
}

BOOL CHttpResponseLine::PreProcess(std::string data)
{
	size_t pos = string::npos;
	if ((pos = data.find(" ")) == string::npos)
		return false;
	version = data.substr(0, pos);

	StatusCode = data.substr(pos + 1, data.length() - pos - 1);
	if ((pos = StatusCode.find(" ")) == string::npos)
		return false;
	StatusCode = StatusCode.substr(0, pos);

	if ((pos = data.rfind(" ")) == string::npos)
		return false;
	reason = data.substr(pos + 1, data.length() - pos - 1);

	return TRUE;
}
